using Infrastructure.Attribute;
using Infrastructure.Extensions;
using ZR.Model.ProdManage.Dto;
using ZR.Model.ProdManage;
using ZR.Repository;
using ZR.Service.ProdManage.IProdManageService;
using Infrastructure;
using ZR.Model.BaseManage;
using System.Threading.Tasks;

namespace ZR.Service.ProdManage
{
    /// <summary>
    /// 生产计划Service业务层处理
    /// </summary>
    [AppService(ServiceType = typeof(IProdPlanService), ServiceLifetime = LifeTime.Transient)]
    public class ProdPlanService : BaseService<ProdPlan>, IProdPlanService
    {
        /// <summary>
        /// 查询生产计划列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<ProdPlanDto> GetPageList(ProdPlanQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
                .Where(predicate.ToExpression())
                .ToPage<ProdPlan, ProdPlanDto>(parm);

            return response;
        }


        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="PlanNo"></param>
        /// <returns></returns>
        public ProdPlan GetInfo(string PlanNo)
        {
            var response = Queryable()
                .Where(x => x.PlanNo == PlanNo)
                .First();

            return response;
        }

        /// <summary>
        /// 添加生产计划
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ProdPlan AddProdPlan(ProdPlan model)
        {
            return Insertable(model).ExecuteReturnEntity();
        }

        /// <summary>
        /// 修改生产计划
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int UpdateProdPlan(ProdPlan model)
        {
            return Update(model, false);
        }

        /// <summary>
        /// 导入生产计划
        /// </summary>
        /// <returns></returns>
        public (string, object, object) ImportProdPlan(List<ProdPlan> list)
        {
            var x = Context.Storageable(list)
                .SplitInsert(it => !it.Any())
                .SplitError(x => x.Item.PlanNo.IsEmpty(), "计划编号不能为空")
                .SplitError(x => x.Item.DmsOrderNo.IsEmpty(), "DMS订单不能为空")
                .SplitError(x => x.Item.ItemNo.IsEmpty(), "产品编号不能为空")
                .SplitError(x => x.Item.ItemType.IsEmpty(), "产品类型不能为空")
                .SplitError(x => x.Item.Qty.IsEmpty(), "数量不能为空")
                .ToStorage();
            x.AsInsertable.ExecuteCommand();//插入可插入部分;

            string msg = $"插入{x.InsertList.Count} 更新{x.UpdateList.Count} 错误数据{x.ErrorList.Count} 不计算数据{x.IgnoreList.Count} 删除数据{x.DeleteList.Count} 总共{x.TotalList.Count}";
            Console.WriteLine(msg);

            ////输出错误信息               
            //foreach (var item in x.ErrorList)
            //{
            //    Console.WriteLine("错误" + item.StorageMessage);
            //}
            //foreach (var item in x.IgnoreList)
            //{
            //    Console.WriteLine("忽略" + item.StorageMessage);
            //}

            return (msg, x.ErrorList, x.IgnoreList);
        }

        /// <summary>
        /// 导出生产计划
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<ProdPlanDto> ExportList(ProdPlanQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
                .Where(predicate.ToExpression())
                .Select((it) => new ProdPlanDto()
                {
                }, true)
                .ToPage(parm);

            return response;
        }

        /// <summary>
        /// 查询导出表达式
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static Expressionable<ProdPlan> QueryExp(ProdPlanQueryDto parm)
        {
            var predicate = Expressionable.Create<ProdPlan>();

            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.PlanNo), it => it.PlanNo == parm.PlanNo);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.SourceCode), it => it.SourceCode == parm.SourceCode);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.DmsOrderNo), it => it.DmsOrderNo == parm.DmsOrderNo);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.ItemNo), it => it.ItemNo == parm.ItemNo);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Status), it => it.Status == parm.Status);
            return predicate;
        }

        /// <summary>
        /// 生产计划推送
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public async Task<bool> CogradientProdPlan(List<WmsPlanDto> list)
        {
            if (list == null || list.Count == 0) throw new CustomException("推送的生产计划信息为空");

            //判断是否已经推送计划
            List<string> codes = list.Select(x => x.planNo).Distinct().ToList();
            List<ProdPlan> oldList = Queryable().Where(it => codes.Contains(it.PlanNo)).ToList();

            List<ProdPlan> addList = new List<ProdPlan>();
            foreach (var item in list)
            {
                if (oldList.Any(it => it.PlanNo == item.planNo)) continue;

                ProdPlan prod = new ProdPlan()
                {
                    PlanNo = item.planNo,
                    SourceCode = item.planNo,
                    DmsOrderNo = item.dmsOrderNo,
                    Address = item.address,
                    Configuration = item.configuration,
                    Country = item.country,
                    Customer = item.customer,
                    ItemNo = item.itemNo,
                    ItemType = item.itemType,
                    PlanTime = item.planTime,
                    Qty = item.qty,
                    Status = item.status,
                    SendStatus = item.sendStatus,
                    QmsSendStatus = item.sendStatus,
                    CreateBy = "wms",
                    CreateTime = DateTime.Now
                };
                addList.Add(prod);
            }

            //执行事务
            var db = this.Context.Ado;
            var res = await db.UseTranAsync(async () =>
            {
                if (addList.Count > 0)
                {
                    await db.Context.Insertable(addList).ExecuteCommandAsync();
                }
                return true;
            });
            if (res.Data == false)
            {
                throw new CustomException(res.ErrorMessage);
            }

            return true;
        }
    }
}